package com.xlongwei.service;

import java.io.File;

import org.noear.snack.ONode;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.annotation.Param;
import org.noear.solon.core.handle.UploadedFile;
import org.noear.solon.validation.annotation.Length;
import org.noear.solon.validation.annotation.NotBlank;

import com.xlongwei.util.ImageUtil;
import com.xlongwei.util.UploadUtil;
import com.xlongwei.util.ZxingUtil;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;

@Controller
@Mapping("service/qrcode")
public class Qrcode {

    @Mapping("encode")
    public ONode encode(@Param @NotBlank String content, @Param String forground, @Param String background,
            @Param(defaultValue = "256") int size, @Param String logo, @Param UploadedFile img,
            @Param(defaultValue = "true") boolean base64Image) throws Exception {
        ONode n = new ONode();
        if (img != null) {
            logo = ImageUtil.encode(IoUtil.readBytes(img.content), null);
        }
        byte[] encode = ZxingUtil.encode(content, size, logo, ZxingUtil.getColor(forground),
                ZxingUtil.getColor(background));
        encode(n, encode, base64Image);
        return n;
    }

    @Mapping("decode")
    public ONode decode(@Param String url, @Param String base64, @Param UploadedFile img) throws Exception {
        ONode n = new ONode();
        byte[] bytes = null;
        if (url != null && url.startsWith("http")) {
            bytes = IoUtil.readBytes(URLUtil.getStream(URLUtil.url(url)));
        }
        if (bytes == null && ImageUtil.isBase64(base64)) {
            bytes = ImageUtil.decode(base64);
        }
        if (bytes == null && img != null) {
            bytes = IoUtil.readBytes(img.content);
        }
        if (bytes != null) {
            String decode = ZxingUtil.decode(bytes);
            if (StrUtil.isNotBlank(decode)) {
                n.set("content", decode);
            }
        }
        return n;
    }

    @Mapping("barcode")
    public ONode barcode(@Param @NotBlank @Length(max = 80) String content, @Param(defaultValue = "5") int margin,
            @Param(defaultValue = "50") int height, @Param(defaultValue = "true") boolean base64Image)
            throws Exception {
        ONode n = new ONode();
        byte[] encode = ZxingUtil.barcode(content, margin, height);
        encode(n, encode, base64Image);
        return n;
    }

    private void encode(ONode n, byte[] encode, boolean base64Image) {
        if (encode == null) {
            return;
        }
        if (base64Image) {
            n.set("base64Image", ImageUtil.encode(encode, null));
        } else {
            String path = "image/" + IdUtil.nanoId() + ".png";
            File target = new File(UploadUtil.SAVE_TEMP, path);
            FileUtil.writeBytes(encode, target);
            if (target.exists()) {
                n.set(UploadUtil.DOMAIN, UploadUtil.URL_TEMP);
                n.set(UploadUtil.PATH, path);
                n.set("url", UploadUtil.URL_TEMP + path);
            }
        }
    }
}
